
<!DOCTYPE html>
<html lang="zh-CN" class="loading">
<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Promise 学习笔记（全） - niko</title>
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="google" content="notranslate" />
    <meta name="keywords" content="TriDiamond Obsidian,"> 
    <meta name="description" content="我想分享给你一些我的想法,Promise  学习笔记释义:1.用于异步计算
2.一个promise 表示一个现在，将来或用不可能使用的值 ( 可以将异步操作队列化，按照期望的顺序执行，返回符合预期的结果。)
3.可以在对象之,"> 
    <meta name="author" content="niko"> 
    <link rel="alternative" href="atom.xml" title="niko" type="application/atom+xml"> 
    <link rel="icon" href="/img/logo_icon.png"> 
    <link href="https://fonts.loli.net/css?family=Roboto+Mono|Rubik&display=swap" rel="stylesheet">
    
<link rel="stylesheet" href="//at.alicdn.com/t/font_1429596_nzgqgvnmkjb.css">

    
<link rel="stylesheet" href="//cdn.bootcss.com/animate.css/3.7.2/animate.min.css">

    
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/css/share.min.css">

    
<link rel="stylesheet" href="//cdn.bootcss.com/codemirror/5.48.4/codemirror.min.css">

    
<link rel="stylesheet" href="//cdn.bootcss.com/codemirror/5.48.4/theme/dracula.css">

    
<link rel="stylesheet" href="/css/obsidian.css">

    
<link rel="stylesheet" href="/css/ball-atom.min.css">

<meta name="generator" content="Hexo 4.2.0"></head>


<body class="loading">
    <div class="loader">
        <div class="la-ball-atom la-2x">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
    <span id="config-title" style="display:none">niko</span>
    <div id="loader"></div>
    <div id="single">
    <div class="scrollbar gradient-bg-rev"></div>
<div id="top" style="display: block;">
    <div class="bar" style="width: 0;"></div>
    <div class="navigation animated fadeIn fast delay-1s">
        <img id="home-icon" class="icon-home" src="/img/logo_icon.png" alt="" data-url="http://yoursite.com">
        <div id="play-icon" title="Play/Pause" class="iconfont icon-play"></div>
        <h3 class="subtitle">Promise 学习笔记（全）</h3>
        <div class="social">
            <!--        <div class="like-icon">-->
            <!--            <a href="javascript:;" class="likeThis active"><span class="icon-like"></span><span class="count">76</span></a>-->
            <!--        </div>-->
            <div>
                <div class="share">
                    
                        <a href="javascript:;" class="iconfont icon-share1"></a>
                        <div class="share-component-cc" data-disabled="facebook,douban,linkedin,diandian,tencent,google"></div>
                    
                </div>
            </div>
        </div>
    </div>
</div>

    <div class="section">
        <div class=article-header-wrapper>
    <div class="article-header">
        <div class="article-cover animated fadeIn" style="
            animation-delay: 600ms;
            animation-duration: 1.2s;
            background-image: 
                radial-gradient(ellipse closest-side, rgba(0, 0, 0, 0.65), #100e17),
                url(/img/cover.jpg) ">
        </div>
        <div class="else">
            <p class="animated fadeInDown">
                
                <a href="/categories/EcmaJs6"><b>「
                    </b>ECMAJS6<b> 」</b></a>
                
                三月 13, 2018
            </p>
            <h3 class="post-title animated fadeInDown"><a href="/2018/03/13/Promise-%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%88%E5%85%A8%EF%BC%89/" title="Promise 学习笔记（全）" class="">Promise 学习笔记（全）</a>
            </h3>
            
            <p class="post-count animated fadeInDown">
                
                <span>
                    <b class="iconfont icon-text2"></b> <i>文章字数</i>
                    6.9k
                </span>
                
                
                <span>
                    <b class="iconfont icon-timer__s"></b> <i>阅读约需</i>
                    6 mins.
                </span>
                
                
                <span id="/2018/03/13/Promise-学习笔记（全）/" class="leancloud_visitors" data-flag-title="Promise 学习笔记（全）">
                    <b class="iconfont icon-read"></b> <i>阅读次数</i>
                    <span class="leancloud-visitors-count">1000000</span>
                </span>
                
                
            </p>
            
            
            <ul class="animated fadeInDown post-tags-list" itemprop="keywords"><li class="animated fadeInDown post-tags-list-item"><a class="animated fadeInDown post-tags-list-link" href="/tags/es6/" rel="tag">es6</a></li></ul>
            
        </div>
    </div>
</div>

<div class="screen-gradient-after">
    <div class="screen-gradient-content">
        <div class="screen-gradient-content-inside">
            <div class="bold-underline-links screen-gradient-sponsor">
                <p>
                    <span class="animated fadeIn delay-1s"></span>
                </p>
            </div>
        </div>
    </div>
</div>

<div class="article">
    <div class='main'>
        <div class="content markdown animated fadeIn">
            <h3 id="Promise-学习笔记"><a href="#Promise-学习笔记" class="headerlink" title="Promise  学习笔记"></a>Promise  学习笔记</h3><h3 id="释义"><a href="#释义" class="headerlink" title="释义:"></a><strong>释义:</strong></h3><p>1.用于异步计算</p>
<p>2.一个promise 表示一个现在，将来或用不可能使用的值 ( 可以将异步操作队列化，按照期望的顺序执行，返回符合预期的结果。)</p>
<p>3.可以在对象之间传递和操作promise ，帮助我们处理队列</p>
<a id="more"></a>

<h3 id="异步回调的四个问题"><a href="#异步回调的四个问题" class="headerlink" title="异步回调的四个问题:"></a><strong>异步回调的四个问题:</strong></h3><ol>
<li>嵌套层次很深，容易陷入回调地域 ，很难维护  </li>
<li>无法正常使用 return  和  throw</li>
<li>无法正常检索堆栈信息，因为每一次回调都是系统层面上的新的堆栈 。</li>
<li>在多个回调之间难以建立联系。</li>
</ol>
<h3 id="Promise-结构"><a href="#Promise-结构" class="headerlink" title="Promise 结构:"></a><strong>Promise 结构:</strong></h3><pre><code class="javascript">new Promise(
    //执行器 executor
    function (resolve,reject) {
        //一段耗时很长的异步操作
        resolve() ; //数据处理完成
        reject() ; //数据处理出错
    }

)
.then(function A(){
    //成功 下一步
},function B(){
    // 失败，做相应的处理
})</code></pre>
<h6 id="1-Promise-是一个代理对象，它和原先要进行的操作并无关系。只是将原来操作放入了executor"><a href="#1-Promise-是一个代理对象，它和原先要进行的操作并无关系。只是将原来操作放入了executor" class="headerlink" title="1.Promise 是一个代理对象，它和原先要进行的操作并无关系。只是将原来操作放入了executor"></a>1.Promise 是一个代理对象，它和原先要进行的操作并无关系。只是将原来操作放入了<code>executor</code></h6><h6 id="2-它通过引入一个回调，避免更多的回调"><a href="#2-它通过引入一个回调，避免更多的回调" class="headerlink" title="2.它通过引入一个回调，避免更多的回调"></a>2.它通过引入一个回调，避免更多的回调</h6><h3 id="Promise三个状态"><a href="#Promise三个状态" class="headerlink" title="*Promise三个状态 *"></a>*<em>Promise三个状态 *</em></h3><ol>
<li><code>pending</code> 待定状态</li>
<li>如果调用 <code>resolve()</code> 就进入  <code>fulfilled</code> 实现 操作成功状态</li>
<li>如果 <code>reject()</code> 就进入 <code>rejected</code> 被否决状态 操作失败</li>
</ol>
<p>当 promise 状态发生改变的时候，就会立即触发<code>.then()</code>离得响应函数，处理后续步骤</p>
<p>Promise 状态一经改变就不会改变</p>
<p>执行流程图  </p>
<p><img src="./1520911191668.png" alt="执行流程图"></p>
<h3 id="then-函数"><a href="#then-函数" class="headerlink" title=".then()函数"></a><strong>.then()函数</strong></h3><pre><code class="javascript">// 假如在.then()的函数里面不返回新的Promise，会怎样？
// https://www.imooc.com/video/16616

console.log(&#39;here we go&#39;);
new Promise(resolve =&gt; {
    setTimeout( () =&gt; {
        resolve(&#39;hello&#39;);
    }, 2000);
})
    .then( value =&gt; {
        console.log(value);
        console.log(&#39;everyone&#39;);
        (function () {
            return new Promise(resolve =&gt; {
                setTimeout(() =&gt; {
                    console.log(&#39;Mr.Laurence&#39;);
                    resolve(&#39;Merry Xmas&#39;);
                }, 2000);
            });
        }());
        return false;
    })
    .then( value =&gt; {
        console.log(value + &#39; world&#39;);
    });

结果：
here we go
hello
everyone
false world
Mr.Laurence</code></pre>
<p><code>.then()</code>  接受两个函数作为参数，分别代表 <code>fulfilled</code> 和 ‘rejected’</p>
<p><code>.then()</code> 返回一个新的Promise 实例，所以它可以链式调用</p>
<p>当前面的    <code>Promise</code> 状态改变时，<code>.then()</code> 根据其最终状态，选择特定的状态响应函数执行 。</p>
<p>状态响应函数可以反悔新的<code>Promise</code> ，或其它值</p>
<p>如果返回新的 <code>Promise</code> ，那么下一级 <code>.then()</code> 会在新 Promise 状态改变之后执行</p>
<p>如果返回其它任何值，则会立即执行下一级 <code>.then()</code>   </p>
<h4 id="then-里面有-then-的情况"><a href="#then-里面有-then-的情况" class="headerlink" title=".then() 里面有 .then() 的情况"></a>.then() 里面有 .then() 的情况</h4><ol>
<li><p>因为 <code>.then()</code> 返回的还是Promise 实例</p>
</li>
<li><p>外层的 <code>.then</code> 会等到 里面的<code>.then()</code>执行完成 再执行</p>
</li>
<li><p>对于我们来书，此时最好将其展开，会更好读</p>
</li>
</ol>
<pre><code class="javascript">// 嵌套.then()
// https://www.imooc.com/video/16618

console.log(&#39;start&#39;);
new Promise( resolve =&gt; {
    console.log(&#39;Step 1&#39;);
    setTimeout(() =&gt; {
        resolve(100);
    }, 1000);
})
    .then( value =&gt; {
        return new Promise(resolve =&gt; {
            console.log(&#39;Step 1-1&#39;);
            setTimeout(() =&gt; {
                resolve(110);
            }, 1000);
        })
            .then( value =&gt; {
                console.log(&#39;Step 1-2&#39;);
                return value;
            })
            .then( value =&gt; {
                console.log(&#39;Step 1-3&#39;);
                return value;
            });
    })
    .then(value =&gt; {
        console.log(value);
        console.log(&#39;Step 2&#39;);
    });

结果：
start
step 1
step 1-1
step 1-2
step 1-3
110
step 2</code></pre>
<h3 id="思考："><a href="#思考：" class="headerlink" title="思考："></a><strong>思考：</strong></h3><p>以下问题出自：<br><a href="https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html" target="_blank" rel="noopener">原文：We have a problem with promises</a><br><a href="http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/" target="_blank" rel="noopener">FEX 中文翻译</a><br><a href="https://www.imooc.com/video/16619/0" target="_blank" rel="noopener">慕课网视频讲解</a></p>
<h5 id="以下四种Promise-的区别是什么呢？"><a href="#以下四种Promise-的区别是什么呢？" class="headerlink" title="以下四种Promise 的区别是什么呢？"></a>以下四种Promise 的区别是什么呢？</h5><pre><code class="javascript">doSomething().then(function () {
  return doSomethingElse();
});

doSomething().then(function () {
  doSomethingElse();
});

doSomething().then(doSomethingElse());

doSomething().then(doSomethingElse);</code></pre>
<h5 id="答案-："><a href="#答案-：" class="headerlink" title="答案 ："></a>答案 ：</h5><pre><code class="javascript">第一题：
doSomething().then(function () {
  return doSomethingElse();
}).then(finalHandler);

doSomething
|-----------------|
                  doSomethingElse(undefined)
                  |------------------|
                                     finalHandler(resultOfDoSomethingElse)
                                     |------------------|
第二题：
doSomething().then(function () {
  doSomethingElse();
}).then(finalHandler);

doSomething
|-----------------|
                  doSomethingElse(undefined)
                  |------------------|
                  finalHandler(undefined)
                  |------------------|

第三题：

doSomething().then(doSomethingElse())
  .then(finalHandler);


doSomething
|-----------------|
doSomethingElse(undefined)
|---------------------------------|
                  finalHandler(resultOfDoSomething)
                  |------------------|

第四题：
doSomething().then(doSomethingElse)
  .then(finalHandler);

doSomething
|-----------------|
                  doSomethingElse(resultOfDoSomething)
                  |------------------|
                                     finalHandler(resultOfDoSomethingElse)
                                     |------------------|
</code></pre>
<h4 id="版权说明：以上均为-慕课网课程：Promise-入门-学习笔记-如有侵权联系我删除"><a href="#版权说明：以上均为-慕课网课程：Promise-入门-学习笔记-如有侵权联系我删除" class="headerlink" title="版权说明：以上均为 慕课网课程：Promise 入门 学习笔记,如有侵权联系我删除"></a>版权说明：以上均为 <a href="https://www.imooc.com/learn/949" target="_blank" rel="noopener">慕课网课程：Promise 入门</a> 学习笔记,如有侵权<a href="18735443767">联系我</a>删除</h4>
            <!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->
            <audio id="audio" loop="1" preload="auto" controls="controls"
                data-autoplay="false">
                <source type="audio/mpeg" src="">
            </audio>
            
            <ul id="audio-list" style="display:none">
                
                
                <li title='0' data-url='/statics/chengdu.mp3'></li>
                
                    
            </ul>
            
            
            
    <div id='gitalk-container' class="comment link"
        data-ae='true'
        data-ci='ec894e2b66f752e8b7fb'
        data-cs='3ccc2e92bb350688fe2c2dc2930189b62622bfb1'
        data-r='blog-comments'
        data-o='TriDiamond'
        data-a='TriDiamond'
        data-d=''
    >留言</div>


            
            
            <div id="vcomments"></div>
            
        </div>
        <div class="sidebar">
            <div class="box animated fadeInRight">
                <div class="subbox">
                    <img src="https://res.cloudinary.com/tridiamond/image/upload/v1573019751/TriDiamond_logo_ui_xeublz.jpg" height=300 width=300></img>
                    <p>niko</p>
                    <span>Think like an artist, develop like an artisan</span>
                    <dl>
                        <dd><a href="https://github.com/TriDiamond" target="_blank"><span
                                    class=" iconfont icon-github"></span></a></dd>
                        <dd><a href="https://twitter.com/TriDiamond6" target="_blank"><span
                                    class=" iconfont icon-twitter"></span></a></dd>
                        <dd><a href="https://stackoverflow.com/users/7602324/tridiamond?tab=profile" target="_blank"><span
                                    class=" iconfont icon-stack-overflow"></span></a></dd>
                    </dl>
                </div>
                <ul>
                    <li><a href="/">20 <p>文章</p></a></li>
                    <li><a href="/categories">10 <p>分类</p></a></li>
                    <li><a href="/tags">11 <p>标签</p></a></li>
                </ul>
            </div>
            
            
            
            <div class="box sticky animated fadeInRight faster">
                <div id="toc" class="subbox">
                    <h4>目录</h4>
                    <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-学习笔记"><span class="toc-number">1.</span> <span class="toc-text">Promise  学习笔记</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#释义"><span class="toc-number">2.</span> <span class="toc-text">释义:</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#异步回调的四个问题"><span class="toc-number">3.</span> <span class="toc-text">异步回调的四个问题:</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-结构"><span class="toc-number">4.</span> <span class="toc-text">Promise 结构:</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise三个状态"><span class="toc-number">5.</span> <span class="toc-text">*Promise三个状态 *</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#then-函数"><span class="toc-number">6.</span> <span class="toc-text">.then()函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#思考："><span class="toc-number">7.</span> <span class="toc-text">思考：</span></a></li></ol>
                </div>
            </div>
            
            
        </div>
    </div>
</div>

    </div>
</div>
    <div id="back-to-top" class="animated fadeIn faster">
        <div class="flow"></div>
        <span class="percentage animated fadeIn faster">0%</span>
        <span class="iconfont icon-top02 animated fadeIn faster"></span>
    </div>
</body>
<footer>
    <p class="copyright" id="copyright">
        &copy; 2020
        <span class="gradient-text">
            niko
        </span>.
        Powered by <a href="http://hexo.io/" title="Hexo" target="_blank" rel="noopener">Hexo</a>
        Theme
        <span class="gradient-text">
            <a href="https://github.com/TriDiamond/hexo-theme-obsidian" title="Obsidian" target="_blank" rel="noopener">Obsidian</a>
        </span>
        <small><a href="https://github.com/TriDiamond/hexo-theme-obsidian/blob/master/CHANGELOG.md" title="v1.4.3" target="_blank" rel="noopener">v1.4.3</a></small>
    </p>
</footer>

<script type="text/javascript" src="https://cdn.bootcss.com/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script>
  MathJax.Hub.Config({
    "HTML-CSS": {
      preferredFont: "TeX",
      availableFonts: ["STIX", "TeX"],
      linebreaks: {
        automatic: true
      },
      EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50)
    },
    tex2jax: {
      inlineMath: [
        ["$", "$"],
        ["\\(", "\\)"]
      ],
      processEscapes: true,
      ignoreClass: "tex2jax_ignore|dno",
      skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    },
    TeX: {
      noUndefined: {
        attributes: {
          mathcolor: "red",
          mathbackground: "#FFEEEE",
          mathsize: "90%"
        }
      },
      Macros: {
        href: "{}"
      }
    },
    messageStyle: "none"
  });
</script>
<script>
  function initialMathJax() {
    MathJax.Hub.Queue(function () {
      var all = MathJax.Hub.getAllJax(),
        i;
      // console.log(all);
      for (i = 0; i < all.length; i += 1) {
        console.log(all[i].SourceElement().parentNode)
        all[i].SourceElement().parentNode.className += ' has-jax';
      }
    });
  }

  function reprocessMathJax() {
    if (typeof MathJax !== 'undefined') {
      MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
    }
  }
</script>



    
<link rel="stylesheet" href="//cdn.bootcss.com/gitalk/1.5.0/gitalk.min.css">

    
<script src="//cdn.bootcss.com/gitalk/1.5.0/gitalk.min.js"></script>



<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="/js/plugin.js"></script>
<script src="/js/obsidian.js"></script>
<script src="/js/jquery.truncate.js"></script>
<script src="/js/search.js"></script>


<script src="//cdn.bootcss.com/typed.js/2.0.10/typed.min.js"></script>


<script src="//cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js"></script>


<script src="//cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/js/social-share.min.js"></script>


<script src="https://cdn.bootcss.com/codemirror/5.48.4/codemirror.min.js"></script>

    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/javascript/javascript.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/css/css.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/xml/xml.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/htmlmixed/htmlmixed.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/clike/clike.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/php/php.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/shell/shell.min.js"></script>


    
<script src="//cdn.bootcss.com/codemirror/5.48.4/mode/python/python.min.js"></script>




    
<script src="/js/busuanzi.min.js"></script>

    <script>
        $(document).ready(function () {
            if ($('span[id^="busuanzi_"]').length) {
                initialBusuanzi();
            }
        });
    </script>



<link rel="stylesheet" href="//cdn.bootcss.com/photoswipe/4.1.3/photoswipe.min.css">
<link rel="stylesheet" href="//cdn.bootcss.com/photoswipe/4.1.3/default-skin/default-skin.min.css">


<script src="//cdn.bootcss.com/photoswipe/4.1.3/photoswipe.min.js"></script>
<script src="//cdn.bootcss.com/photoswipe/4.1.3/photoswipe-ui-default.min.js"></script>


<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>
    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">
        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>
        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">
            <div class="pswp__top-bar">
                <!--  Controls are self-explanatory. Order can be changed. -->
                <div class="pswp__counter"></div>
                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
                <button class="pswp__button pswp__button--share" title="Share"></button>
                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                      <div class="pswp__preloader__cut">
                        <div class="pswp__preloader__donut"></div>
                      </div>
                    </div>
                </div>
            </div>
            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div> 
            </div>
            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>
            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>
            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>
        </div>
    </div>
</div>



    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="//www.googletagmanager.com/gtag/js?id=UA-149874671-1"></script>
    <script>
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());

        gtag('config', 'UA-149874671-1');
    </script>





<script>
    function initialTyped () {
        var typedTextEl = $('.typed-text');
        if (typedTextEl && typedTextEl.length > 0) {
            var typed = new Typed('.typed-text', {
                strings: ["Think like an artist, develop like an artisan", "艺术家思维去思考问题，工匠创造精神去开发"],
                typeSpeed: 90,
                loop: true,
                loopCount: Infinity,
                backSpeed: 20,
            });
        }
    }

    if ($('.article-header') && $('.article-header').length) {
        $(document).ready(function () {
            initialTyped();
        });
    }
</script>


    
<script src="//unpkg.com/valine/dist/Valine.min.js"></script>

    <script>

        var valine = new Valine();

        function initValine(path) {
            if (!path) path = window.location.pathname;
            let language = 'zh-CN';
            if (!language) {
                language = 'en';
            } else {
                language = language.toLowerCase();
            }
            valine.init({
                el: '#vcomments',
                appId: 'h0Nbcp32WtIpnnHaGTLWbtKo-gzGzoHsz',
                appKey: 'hPhFiAi2vIj2OStCIi79waty',
                notify: 'false',
                verify: 'false',
                avatar: 'happ_niko',
                placeholder: '快写下你的想法与我互动',
                visitor: 'true',
                path: path,
                lang: language
            });
        }

        $(document).ready(function () {
            initValine();
        });
    </script>



</html>
